
'use strict'

const url = require('url');
const https = require('https');

var it_faxian = undefined
var it_jingxuan = undefined

const POSTED = {};

const config = {
	CRAWLE_MAX: 7200,		// 搜索 2 小时内的爆料（秒）
	EACH_INTERVAL: 10000,	// 距离本轮下次搜索开始的间隔时间（毫秒）
	NEXT_INTERVAL: 60000,	// 距离下一轮搜索开始的间隔时间（毫秒）
	RATES_MIN: 8,			// 点赞数下限
	COMMENTS_MIN: 8,		// 评论数下限
	RMB_MAX: 0,				// 价格上限
	EXCEPT_CATELOG: [
		'母婴用品',
		'服饰鞋包',
		'汽车消费',
		'个护化妆'
	],
	EXCEPT_KEYWORDS: [		// 要排除的关键字
		'运动鞋', '拖鞋', '休闲鞋', '葡萄酒', '白酒', '运动裤'
	],
	WECHAT_KEY: '763863bc-3604-4409-b336-a9216f6827c3', // 企业微信机器人 KEY
	SERVER_CHAN_SCKEY: 'SCU111897T43c0426eda0dc05f78e73cc2c3edad5d5f4f6429e66b8', // Server 酱公众号 SCKEY
};

var interval = 1000

process.on('SIGINT', function () {
	console.log('收到 CTRL+C');
	if ('undefined' !== typeof(it_faxian)) {
		clearTimeout(it_faxian);
	}

	if ('undefined' !== typeof(it_jingxuan)) {
		clearTimeout(it_jingxuan);
	}

	process.exit();
});

process.on('uncaughtException', function (err, origin) {
	console.error(err)
	console.error(origin)
});

process.on('exit', function (code) {
	console.log('退出码：%d', code);
});

function request(options, postData, cb) {
	const req = https.request(options, function (res) {
		if (200 != res.statusCode) {
			if (302 === res.statusCode) {
				console.log('https://%s/%s/ redirecting to %s', options.hostname, options.path, res.headers.location);

				const redirect_url = url.parse(res.headers.location);
				options.hostname = redirect_url.hostname;
				options.path = redirect_url.path;
				request(options, postData, cb);
				return
			}

			cb(undefined, new Error('statusCode err'));
			return
		}

		let data = [];
		res.setEncoding('utf8');
		res.on('data', function (chunk) {
			data.push(chunk);
		}).on('end', function () {
			data = ''.concat(...data);

			cb(data, undefined);
		});
	});

	req.on('error', function (err) {
		cb(undefined, err);
	});

	if ('string' === typeof(postData) && postData.length > 0) {
		req.write(postData);
	}

	req.end();
}

function postToWeChat(data) {
	const postData = JSON.stringify({
		msgtype: 'news',
		news: {
			articles: [{
				title: data.title,
				description: data.price,
				url: data.url,
				picurl: data.pic_url
			}]
		}
	});

	// console.log(postData);

	request({
		hostname: 'qyapi.weixin.qq.com',
		port: 443,
		path: '/cgi-bin/webhook/send?key=' + config.WECHAT_KEY,
		method: 'POST',
		headers: {
			'Content-Type': 'application/json; charset=utf-8',
			'Content-Length': Buffer.byteLength(postData)
		}
	}, postData, function (data, err) {
		if (err) {
			console.error('postToWeChat err: %s', err.message);
			return
		}

		// console.log('postToWeChat data: %s', data);
	});
}

function postToServerChan(data) {
	const postData = 
		'text=' + encodeURIComponent(data.title) + '&' +
		'desp=' + encodeURIComponent('![pic](http' + data.pic_url.substr(5) + ')\r\n' +
			'## ' + data.title + '\r\n' +
			'## <font color="#DD0000">价格：' + data.price + '</font>\r\n' +
			'## 点赞数：' + data.rating + '\r\n' +
			'## 评论数：' + data.comment + '\r\n' +
			'## 爆料内容：' + data.content + '\r\n' +
			'## 购买链接：[' + data.url + '](' + data.url + ')');

	// console.log(postData);

	request({
		hostname: 'sc.ftqq.com',
		port: 443,
		path: '/' + config.SERVER_CHAN_SCKEY + '.send',
		method: 'POST',
		headers: {
			'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
			'Content-Length': Buffer.byteLength(postData)
		}
	}, postData, function (data, err) {
		if (err) {
			console.error('postToWeChat err: %s', err.message);
			return
		}

		// console.log('postToWeChat data: %s', data);
	});
}

function query_faxian(tm) {
	it_faxian = setTimeout(function () {
		// 递归
		clearTimeout(it_faxian);

		// https://faxian.smzdm.com/json_more?type=a&timesort=1597977077
		request({
			hostname: 'faxian.smzdm.com',
			port: 443,
			path: '/json_more?type=a&timesort=' + tm,
			method: 'GET'
		}, undefined, function (data, err) {
			if (err) {
				console.error('query_faxian err: %s', err.message);
				query_faxian(tm);
				return
			}

			data = JSON.parse(data);
			// console.log(JSON.stringify(data, null, 4));

			let now = Math.floor(Date.now() / 1000)
			let oldest = now;
			for (let i = 0; i < data.length; i++) {
				if ((config.RATES_MIN > 0 && data[i].article_rating >= config.RATES_MIN) || // 点值数量限制
					(config.COMMENTS_MIN > 0 && data[i].article_comment >= config.COMMENTS_MIN) || // 评论数限制
					(config.RMB_MAX > 0 && data[i].gtm.rmb_price < config.RMB_MAX)) { // 价格限制

					// 关键字过滤
					let is_match = false
					for (let j = 0; j < config.EXCEPT_KEYWORDS.length; j++) {
						if (-1 != data[i].article_title.indexOf(config.EXCEPT_KEYWORDS[j])) {
							is_match = true;
							break;
						}
					}

					if (is_match) {
						continue;
					}

					// 品类过滤
					is_match = false;
					for (let j = 0; j < config.EXCEPT_CATELOG.length; j++) {
						if (-1 != data[i].article_top_category.indexOf(config.EXCEPT_CATELOG[j])) {
							is_match = true;
							break;
						}
					}

					if (is_match) {
						continue;
					}

					// 爆料是否已推送
					if ('undefined' !== typeof(POSTED[data[i].article_id])) {
						continue;
					}

					// 记录最后一件爆料的时间，以便刷新下一页
					if (oldest > data[i].timesort) {
						oldest = data[i].timesort;
					}

					POSTED[data[i].article_id] = now;
					console.log(data[i].article_title, '（' + data[i].article_price + '）,', data[i].article_rating,',', data[i].article_comment, '：', data[i].article_url);

					// postToWeChat({
						// title: data[i].article_title,
						// pic_url: data[i].article_pic_url,
						// rating: data[i].article_rating,
						// price: data[i].article_price,
						// comment: data[i].article_comment,
						// content: data[i].article_content,
						// url: data[i].article_url
					// });

					postToServerChan({
						title: data[i].article_title,
						pic_url: data[i].article_pic_url,
						rating: data[i].article_rating,
						price: data[i].article_price,
						comment: data[i].article_comment,
						content: data[i].article_content,
						url: data[i].article_url
					});
				}
			}

			// 每轮搜索最早时间限制
			if (now - oldest >= config.CRAWLE_MAX) { // 下一轮搜索
				oldest = now // 从当前时间再次开始搜索
				interval = config.NEXT_INTERVAL
			} else { // 本轮搜索，从最后一件爆料的时间开始搜索
				interval = config.EACH_INTERVAL
			}

			query_faxian(oldest);
		});
	}, interval, tm);
}

function query_jingxuan(tm) {
	it_jingxuan = setTimeout(function () {
		// 递归
		clearTimeout(it_jingxuan);

		// https://www.smzdm.com/jingxuan/json_more?timesort=1598758223&filter=s0f0t0b0d0r0p0
		request({
			hostname: 'www.smzdm.com',
			port: 443,
			path: '/jingxuan/json_more?filter=s0f0t0b0d0r0p0&timesort=' + tm,
			method: 'GET'
		}, undefined, function (data, err) {
			if (err) {
				console.error('query_jingxuan err: %s', err.message);
				query_jingxuan(tm);
				return
			}

			data = JSON.parse(data);
			// console.log(JSON.stringify(data, null, 4));

			let now = Math.floor(Date.now() / 1000)
			let oldest = now
			for (let i = 0; i < data.article_list.length; i++) {
				const worthies = data.article_list[i].article_worthy + data.article_list[i].article_unworthy;
				if ((config.RATES_MIN > 0 && worthies >= config.RATES_MIN) || // 点值数量限制
					(config.COMMENTS_MIN > 0 && data.article_list[i].article_comment >= config.COMMENTS_MIN) || // 评论数限制
					(config.RMB_MAX > 0 && data.article_list[i].gtm.rmb_price < config.RMB_MAX)) { // 价格限制

					// 关键字过滤
					let is_match = false
					for (let j = 0; j < config.EXCEPT_KEYWORDS.length; j++) {
						if (-1 != data.article_list[i].article_title.indexOf(config.EXCEPT_KEYWORDS[j])) {
							is_match = true;
							break;
						}
					}

					if (is_match) {
						continue;
					}

					// 品类过滤
					is_match = false
					for (let j = 0; j < config.EXCEPT_CATELOG.length; j++) {
						if (-1 != data.article_list[i].gtm.cate_level1.indexOf(config.EXCEPT_CATELOG[j])) {
							is_match = true
							break
						}
					}

					if (is_match) {
						continue
					}

					// 爆料是否已推送
					if ('undefined' !== typeof(POSTED[data.article_list[i].article_id])) {
						continue
					}

					// 记录最后一件爆料的时间，以便刷新下一页
					if (oldest > data.article_list[i].article_timesort) {
						oldest = data.article_list[i].article_timesort
					}

					POSTED[data.article_list[i].article_id] = now
					console.log(data.article_list[i].article_title, '（' + data.article_list[i].article_price + '）,', worthies,',', data.article_list[i].article_comment, '：', data.article_list[i].article_url)

					// postToWeChat({
						// title: data.article_list[i].article_title,
						// pic_url: data.article_list[i].article_pic_url,
						// rating: worthies,
						// price: data.article_list[i].article_price,
						// comment: data.article_list[i].article_comment,
						// content: data.article_list[i].article_content,
						// url: data.article_list[i].article_url
					// });

					postToServerChan({
						title: data.article_list[i].article_title,
						pic_url: data.article_list[i].article_pic_url,
						rating: worthies,
						price: data.article_list[i].article_price,
						comment: data.article_list[i].article_comment,
						content: data.article_list[i].article_content,
						url: data.article_list[i].article_url
					});
				}
			}

			// 每轮搜索最早时间限制
			if (now - oldest >= config.CRAWLE_MAX) { // 下一轮搜索
				oldest = now // 从当前时间再次开始搜索
				interval = config.NEXT_INTERVAL
			} else { // 本轮搜索，从最后一件爆料的时间开始搜索
				interval = config.EACH_INTERVAL
			}

			query_jingxuan(oldest);
		});
	}, interval, tm);
}

query_faxian(Math.floor(Date.now() / 1000));
query_jingxuan(Math.floor(Date.now() / 1000));